package com.seguriapp.complaints.gwt.client;

import java.util.List;

import com.bramosystems.oss.player.core.client.AbstractMediaPlayer;
import com.bramosystems.oss.player.core.client.LoadException;
import com.bramosystems.oss.player.core.client.PlayerUtil;
import com.bramosystems.oss.player.core.client.PluginNotFoundException;
import com.bramosystems.oss.player.core.client.ui.NativePlayer;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.SmallMapControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.seguriapp.common.gwt.client.UtilClientValidations;
import com.seguriapp.complaints.gwt.client.activity.ComplaintDetailsActivity;
import com.seguriapp.complaints.gwt.client.activity.ComplaintDetailsActivity.Display;
import com.seguriapp.entities.Complaint;
import com.seguriapp.entities.MediaContent;
import com.seguriapp.entities.MediaContentType;

public class ComplaintDetailsPage extends Composite implements Display {

  private static final String DOWNLOAD_LINK_TEXT = "Download";
  private static final String DOWNLOAD_LINK_URL = "Download?fileName=";
  private static final String VISIBLE_LINK_TEXT = "Hacer visible la denuncia en mapa de actividad criminal";
  private static final String NO_VISIBLE_LINK_TEXT = "Hacer no visible la denuncia en mapa de actividad criminal";

  private static ComplaintDetailsPageUiBinder uiBinder = GWT.create(ComplaintDetailsPageUiBinder.class);

  interface ComplaintDetailsPageUiBinder extends UiBinder<Widget, ComplaintDetailsPage> {
  }

  private ComplaintDetailsActivity presenter;
  private MapWidget map;

  @UiField
  protected HTMLPanel mapPanel;
  @UiField
  protected HTMLPanel errorMessage;
  @UiField
  protected HTMLPanel detailsContent;
  @UiField
  protected HTMLPanel mediaErrorMessage;
  @UiField
  protected HTMLPanel mediaGallery;
  @UiField
  protected HTMLPanel imageGallery;
  @UiField
  protected HTMLPanel videoGallery;
  @UiField
  protected HTMLPanel audioGallery;
  @UiField
  protected Label nameslbl;
  @UiField
  protected Label dnilbl;
  @UiField
  protected Label datelbl;
  @UiField
  protected Label placelbl;
  @UiField
  protected Label phonelbl;
  @UiField
  protected Label emaillbl;
  @UiField
  protected Label commentlbl;
  @UiField
  protected Anchor viewInCAMapHyperlink;
  @UiField
  protected Label viewInCAMapErrorlbl;

  public ComplaintDetailsPage() {
    initWidget(uiBinder.createAndBindUi(this));
  }

  public void setPresenter(final ComplaintDetailsActivity presenter) {
    this.presenter = presenter;
  }

  public void setNoDataMessage() {
    errorMessage.setVisible(true);
    detailsContent.setVisible(false);
  }

  public void setData(final Complaint complaint) {
    errorMessage.setVisible(false);
    detailsContent.setVisible(true);
    final LatLng latLng = LatLng.newInstance(complaint.getCrimeLatitude(), complaint.getCrimeLongitude());
    map = new MapWidget(latLng, 13);
    map.setSize("500px", "300px");
    final Marker marker = new Marker(latLng);
    map.addOverlay(marker);
    map.setScrollWheelZoomEnabled(true);
    map.addControl(new SmallMapControl());
    // getLocationData(latLng);
    nameslbl.setText(complaint.getNames().concat(" ").concat(complaint.getLastNames()));
    dnilbl.setText(complaint.getDni());
    datelbl.setText(UtilClientValidations.DATE_VIEW_FORMAT.format(complaint.getCrimeDate()));
    commentlbl.setText(complaint.getDescription());
    phonelbl.setText(complaint.getPhone());
    emaillbl.setText(complaint.getEmail());
    placelbl.setText(complaint.getAddress());
    viewInCAMapHyperlink.setText(complaint.isMapVisivility() ? NO_VISIBLE_LINK_TEXT : VISIBLE_LINK_TEXT);
    viewInCAMapErrorlbl.setVisible(false);
    mapPanel.clear();
    mapPanel.add(map);
  }

  @UiHandler("viewInCAMapHyperlink")
  protected void onViewInCAMapHyperlinkClick(final ClickEvent event) {
    presenter.changeComplaintVisibility(viewInCAMapHyperlink.getText().equals(VISIBLE_LINK_TEXT));
  }

  public void setMediaData(final List<MediaContent> mediaDataList, final String audioUrl, final String imageUrl, final String videoUrl,
      final String audioValidExt, final String videoValidExt) {
    mediaErrorMessage.setVisible(false);
    mediaGallery.setVisible(true);
    cleanMediaGalleries();
    for (final MediaContent mediaContent : mediaDataList) {
      if (MediaContentType.Image.equals(mediaContent.getType())) {
        final Image image = new Image(imageUrl.replace("{imageName}", mediaContent.getContent()));

        image.addClickHandler(new ClickHandler() {

          public void onClick(ClickEvent event) {
            openImagePopup(new Image(imageUrl.replace("{imageName}", mediaContent.getContent())));
          }

        });

        imageGallery.add(image);

      } else if (MediaContentType.Audio.equals(mediaContent.getType())) {
        if (hasFileValidExtension(mediaContent.getContent(), audioValidExt)) {
          audioGallery.add(getDownloadLink(mediaContent));
        } else {
          final String mediaHref = audioUrl.replace("{videoName}", mediaContent.getContent());
          try {
            // create the player, specifing URL of media
            final AbstractMediaPlayer player = new NativePlayer(mediaHref, false, "200px", "300px");
            audioGallery.add(player); // add player to panel.
          } catch (LoadException e) {
            // catch loading exception and alert user
            // showVideoErrorMessage("An error occured while loading");
            audioGallery.add(getDownloadLink(mediaContent));
          } catch (PluginNotFoundException e) {
            // catch PluginNotFoundException, thrown if client
            // browser is not HTML 5 compliant
            audioGallery.add(getDownloadLink(mediaContent));
            audioGallery.add(PlayerUtil.getMissingPluginNotice(e.getPlugin()));
          }
        }
      } else if (MediaContentType.Video.equals(mediaContent.getType())) {
        if (hasFileValidExtension(mediaContent.getContent(), videoValidExt)) {
          audioGallery.add(getDownloadLink(mediaContent));
        } else {
          final String mediaHref = videoUrl.replace("{videoName}", mediaContent.getContent());
          try {
            // create the player, specifing URL of media
            final AbstractMediaPlayer player = new NativePlayer(mediaHref, false, "200px", "300px");
            videoGallery.add(player); // add player to panel.
          } catch (LoadException e) {
            // catch loading exception and alert user
            // showVideoErrorMessage("An error occured while loading");
            videoGallery.add(getDownloadLink(mediaContent));
          } catch (PluginNotFoundException e) {
            // catch PluginNotFoundException, thrown if client
            // browser is not HTML 5 compliant
            videoGallery.add(getDownloadLink(mediaContent));
            videoGallery.add(PlayerUtil.getMissingPluginNotice(e.getPlugin()));
          }
        }
      }
    }
  }

  public void showNoMediaDataMessage() {
    cleanMediaGalleries();
    mediaErrorMessage.setVisible(true);
    mediaGallery.setVisible(false);
  }

  public void showVisibilityErrorMsg() {
    viewInCAMapErrorlbl.setVisible(true);
  }

  public void changeVisibilityLinkText(final boolean isVisible) {
    viewInCAMapHyperlink.setText(isVisible ? NO_VISIBLE_LINK_TEXT : VISIBLE_LINK_TEXT);
  }

  @UiHandler("backToListLink")
  protected void onBackToListLinkClick(final ClickEvent event) {
    presenter.goBackToList();
  }

  private void openImagePopup(final Image image) {
    final PopupPanel imagePopup = new PopupPanel(true);
    image.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        imagePopup.hide();
      }
    });
    imagePopup.setAnimationEnabled(true);
    imagePopup.ensureDebugId("cwBasicPopup-imagePopup");
    imagePopup.setWidget(image);
    imagePopup.center();
  }

  private void cleanMediaGalleries() {
    audioGallery.clear();
    imageGallery.clear();
    videoGallery.clear();
  }

  private Anchor getDownloadLink(final MediaContent mediaContent) {
    final Anchor link = new Anchor(DOWNLOAD_LINK_TEXT);
    link.setHref(DOWNLOAD_LINK_URL + mediaContent.getContent() + "&fileType=" + mediaContent.getType().name().toLowerCase());
    return link;
  }

  private boolean hasFileValidExtension(final String fileName, final String validExts) {
    if (validExts == null || validExts.isEmpty()) {
      return false;
    }
    final String[] list = validExts.split(";");
    for (String ext : list) {
      if (fileName.toUpperCase().endsWith("." + ext.toUpperCase())) {
        return true;
      }
    }
    return false;
  }

}
